<template>
  <div class="file-upload-component">
    <el-upload
      ref="uploadRef"
      :action="uploadAction"
      :before-upload="handleBeforeUpload"
      :on-remove="handleRemove"
      :file-list="fileList"
      :limit="limit"
      :multiple="multiple"
      :accept="accept"
      :http-request="customUpload"
      :disabled="disabled"
      :list-type="listType"
    >
      <template #trigger>
        <el-button type="primary" :icon="Upload" :disabled="disabled">
          {{ buttonText }}
        </el-button>
      </template>
      <template #tip>
        <div class="el-upload__tip">
          {{ tipText }}
        </div>
      </template>
    </el-upload>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Upload } from '@element-plus/icons-vue'
import { uploadFile, type FileUploadParams } from '@/api/file'
import type { UploadProps, UploadUserFile, UploadRequestOptions } from 'element-plus'

/**
 * 文件上传组件
 * 
 * 使用示例：
 * <FileUpload
 *   file-type="certificate"
 *   category="certificate"
 *   :student-id="studentId"
 *   :approval-required="1"
 *   :multiple="true"
 *   :limit="5"
 *   @success="handleUploadSuccess"
 * />
 */

interface Props {
  // 文件类型: certificate-证书 medical-医疗证明 transfer-转学证明 id_card-身份证 photo-照片 academic-学籍材料 other-其他
  fileType?: string
  // 文件分类: approval-审批附件 archive-档案附件 certificate-证书材料
  category?: string
  // 关联学生ID
  studentId?: number
  // 关联审批ID
  approvalId?: number
  // 是否需要审核: 0-否 1-是
  approvalRequired?: number
  // 是否允许多选
  multiple?: boolean
  // 文件数量限制
  limit?: number
  // 接受的文件类型
  accept?: string
  // 是否禁用
  disabled?: boolean
  // 按钮文字
  buttonText?: string
  // 提示文字
  tipText?: string
  // 展示类型: text/picture/picture-card
  listType?: 'text' | 'picture' | 'picture-card'
}

const props = withDefaults(defineProps<Props>(), {
  fileType: 'other',
  category: 'archive',
  approvalRequired: 0,
  multiple: false,
  limit: 10,
  accept: '.jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx,.zip,.rar',
  disabled: false,
  buttonText: '选择文件',
  tipText: '支持图片、PDF、Office文档和压缩包，单个文件不超过10MB',
  listType: 'text'
})

const emit = defineEmits<{
  success: [files: any[]]
  error: [error: any]
  remove: [file: any]
}>()

const uploadRef = ref()
const fileList = ref<UploadUserFile[]>([])
const uploadedFiles = ref<any[]>([])

const uploadAction = computed(() => {
  // 这个值不会被真正使用，因为我们使用了自定义上传
  return '/api/file/upload'
})

/**
 * 上传前的校验
 */
const handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {
  // 验证文件大小
  const maxSize = 10 * 1024 * 1024 // 10MB
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过 10MB!')
    return false
  }

  // 验证文件类型
  const allowedTypes = props.accept.split(',')
  const fileName = file.name.toLowerCase()
  const isAllowed = allowedTypes.some(type => {
    const ext = type.trim()
    return fileName.endsWith(ext)
  })

  if (!isAllowed) {
    ElMessage.error('不支持的文件类型!')
    return false
  }

  return true
}

/**
 * 自定义上传
 */
const customUpload = async (options: UploadRequestOptions) => {
  const { file } = options

  const params: FileUploadParams = {
    fileType: props.fileType,
    category: props.category,
    studentId: props.studentId,
    approvalId: props.approvalId,
    approvalRequired: props.approvalRequired
  }

  try {
    // 注意：响应拦截器已经返回了 data 部分，不是完整的 {code, data, message}
    const fileInfo = await uploadFile(file as File, params)
    
    // 直接判断是否有文件信息（id 是必需字段）
    if (fileInfo && fileInfo.id) {
      // 添加文件到已上传列表
      uploadedFiles.value.push(fileInfo)
      
      // 显示成功提示
      ElMessage.success(`文件 ${fileInfo.fileName} 上传成功!`)
      
      // 触发成功事件，传递所有已上传文件
      emit('success', uploadedFiles.value)
    } else {
      throw new Error('上传失败：返回数据格式错误')
    }
  } catch (error: any) {
    console.error('文件上传失败:', error)
    ElMessage.error(`文件上传失败: ${error.message || '未知错误'}`)
    emit('error', error)
    
    // 上传失败时，从文件列表中移除该文件
    const index = fileList.value.findIndex(f => f.name === file.name)
    if (index > -1) {
      fileList.value.splice(index, 1)
    }
  }
}

/**
 * 移除文件
 */
const handleRemove: UploadProps['onRemove'] = (file) => {
  // 从已上传文件列表中移除（通过文件名匹配）
  const index = uploadedFiles.value.findIndex(f => f.fileName === file.name)
  
  if (index > -1) {
    const removedFile = uploadedFiles.value.splice(index, 1)[0]
    console.log('移除文件:', removedFile.fileName)
  }
  
  emit('remove', file)
  emit('success', uploadedFiles.value)
}

/**
 * 清空文件列表
 */
const clearFiles = () => {
  uploadRef.value?.clearFiles()
  uploadedFiles.value = []
}

/**
 * 获取已上传的文件
 */
const getUploadedFiles = () => {
  return uploadedFiles.value
}

// 暴露方法给父组件
defineExpose({
  clearFiles,
  getUploadedFiles
})
</script>

<style scoped lang="scss">
.file-upload-component {
  width: 100%;

  :deep(.el-upload__tip) {
    font-size: 12px;
    color: #999;
    margin-top: 8px;
  }
}
</style>

